<template>
  <view class="chat-container">
    <!-- 聊天消息列表区域 -->
    <scroll-view 
      class="chat-list"
      scroll-y="true"
      :scroll-top="scrollTop"
      :scroll-into-view="scrollToView"
      @scrolltoupper="loadHistory"
      upper-threshold="50"
    >
      <view class="chat-list-content">
        <block v-for="(item, index) in messageList" :key="index">
          <!-- 时间显示 -->
          <view class="chat-time" v-if="item.showTime">
            {{item.time}}
          </view>
          
          <!-- 消息气泡 -->
          <view :class="['chat-item', item.isSelf ? 'chat-item-right' : 'chat-item-left']">
            <!-- 头像 -->
            <image class="avatar" :src="item.avatar || '/static/images/chat/default-avatar.png'" mode="aspectFill"></image>
            
            <!-- 消息内容 -->
            <view class="chat-content">
              <!-- 文本消息 -->
              <view v-if="item.type === 'text'" class="chat-text">{{item.content}}</view>
              
              <!-- 语音消息 -->
              <view v-if="item.type === 'voice'" 
                class="chat-voice"
                @tap="playVoice(item)"
              >
                <view class="voice-icon">
                  <image 
                    :src="item.isSelf ? '/static/images/chat/voice-right.png' : '/static/images/chat/voice-left.png'"
                    :class="['icon-voice', {'playing': item.isPlaying}]"
                    mode="aspectFit"
                  ></image>
                </view>
                <text class="voice-duration">{{item.duration}}''</text>
              </view>
            </view>
          </view>
        </block>
      </view>
    </scroll-view>

    <!-- 底部输入区域 -->
    <view class="chat-footer">
      <!-- 语音/键盘切换按钮 -->
      <view class="mode-btn" @tap="switchInputMode">
        <image 
          :src="isVoiceMode ? '/static/images/chat/keyboard.png' : '/static/images/chat/voice.png'"
          class="mode-icon"
          mode="aspectFit"
        ></image>
      </view>
      
      <!-- Input Area -->
      <template v-if="!isVoiceMode">
        <view class="input-wrapper">
          <input
            class="chat-input"
            v-model="inputContent"
            type="text"
            confirm-type="send"
            @confirm="sendMessage"
            placeholder="请输入消息"
          />
          
          <view 
            class="send-btn"
            :class="{'send-btn-active': inputContent.trim()}"
            @tap="handleSend"
          >发送</view>
        </view>
      </template>
      
      <!-- 语音输入按钮 -->
      <template v-else>
        <view 
          class="voice-input"
          @touchstart="startRecord"
          @touchend="endRecord"
          @touchmove="moveRecord"
        >
          {{recording ? '松开发送' : '按住说话'}}
        </view>
      </template>
    </view>

    <!-- 录音提示蒙层 -->
    <view class="record-modal" v-if="recording">
      <view class="modal-content">
        <view class="record-tip">{{recordTip}}</view>
        <image 
          :src="willCancel ? '/static/images/chat/record-cancel.png' : '/static/images/chat/record-volume.png'"
          class="volume-icon"
          mode="aspectFit"
        ></image>
      </view>
    </view>
  </view>
</template>

<script>
import { mapState } from 'vuex'
import { getToken } from '@/utils/auth'
import { 
  getHistoryMessages,
  sendTextMessage, 
  sendVoiceMessage,
  uploadVoiceFile,
  getCurrentChat
} from '@/api/chat/chat'

export default {
  data() {
    return {
      messageList: [], // 消息列表
      inputContent: '', // 输入框内容
      isVoiceMode: false, // 是否为语音输入模式
      recording: false, // 是否正在录音
      recordTip: '手指上滑,取消发送', // 录音提示文字
      willCancel: false, // 是否将要取消发送语音
      scrollTop: 0, // 滚动条位置
      scrollToView: '', // 滚动到指定元素
      recorderManager: null, // 录音管理器
      innerAudioContext: null, // 音频播放器
      pageNum: 1, // 当前页码
      pageSize: 20, // 每页条数
      total: 0, // 总条数
      loading: false, // 是否正在加载
      chatId: '', // 当前聊天ID
      toUserId: '', // 聊天对象ID
      chatInfo: null // 聊天信息
    }
  },

  computed: {
    ...mapState({
      userInfo: state => state.user
    })
  },

  onLoad(options) {
    // 检查登录状态
    if (!getToken()) {
      uni.reLaunch({
        url: '/pages/login/index'
      })
      return
    }
    
    // 获取路由参数
    this.chatId = options.chatId || ''
    this.toUserId = options.toUserId || ''
    
    // 初始化录音管理器
    this.recorderManager = uni.getRecorderManager()
    this.innerAudioContext = uni.createInnerAudioContext()
    
    // 监听录音结束事件
    this.recorderManager.onStop((res) => {
      if(!this.willCancel) {
        this.sendVoiceMessage(res)
      }
    })
    
    // 获取聊天信息
    this.getChatInfo()
    
    // 加载历史消息
    this.loadHistoryMessages()
  },

  methods: {
    // 获取聊天信息
    async getChatInfo() {
      try {
        const res = await getCurrentChat({
          chatId: this.chatId,
          toUserId: this.toUserId
        })
        this.chatInfo = res.data
        // 如果没有chatId,使用返回的chatId
        if(!this.chatId) {
          this.chatId = this.chatInfo.chatId
        }
      } catch(e) {
        this.$modal.showToast('获取聊天信息失败')
      }
    },

    // 切换输入模式
    switchInputMode() {
      this.isVoiceMode = !this.isVoiceMode
    },

    // 发送文本消息
    async sendMessage() {
      if(!this.inputContent.trim()) return
      
      // 检查用户信息
      if (!this.userInfo) {
        this.$modal.showToast('请先登录')
        return
      }
      
      const message = {
        id: Date.now(),
        type: 'text',
        content: this.inputContent,
        time: new Date().toLocaleTimeString(),
        isSelf: true,
        avatar: this.userInfo.avatar || '/static/images/chat/default-avatar.png',
        showTime: true
      }
      
      // 先添加到列表
      this.messageList.push(message)
      this.inputContent = ''
      this.scrollToBottom()
      
      try {
        // 发送消息到服务器
        await sendTextMessage({
          content: message.content,
          type: 'text',
          chatId: this.chatId,
          toUserId: this.toUserId
        })
      } catch(e) {
        // 发送失败时从列表中移除
        const index = this.messageList.findIndex(item => item.id === message.id)
        if(index > -1) {
          this.messageList.splice(index, 1)
        }
        this.$modal.showToast('发送失败')
      }
    },

    // 开始录音
    startRecord(e) {
      this.recording = true
      this.willCancel = false
      
      this.recorderManager.start({
        duration: 60000, // 最长录音时间
        format: 'mp3'
      })
    },

    // 结束录音
    endRecord(e) {
      this.recording = false
      this.recorderManager.stop()
    },

    // 移动手指事件(判断是否取消发送)
    moveRecord(e) {
      if(e.touches[0].clientY < e.currentTarget.offsetTop - 50) {
        this.willCancel = true
        this.recordTip = '松开手指,取消发送'
      } else {
        this.willCancel = false
        this.recordTip = '手指上滑,取消发送'
      }
    },

    // 发送语音消息
    async sendVoiceMessage(res) {
      if (!this.userInfo) {
        this.$modal.showToast('请先登录')
        return
      }

      const message = {
        id: Date.now(),
        type: 'voice',
        content: res.tempFilePath,
        duration: Math.ceil(res.duration/1000),
        time: new Date().toLocaleTimeString(),
        isSelf: true,
        avatar: this.userInfo.avatar || '/static/images/chat/default-avatar.png',
        showTime: true,
        isPlaying: false
      }
      
      // 先添加到列表
      this.messageList.push(message)
      this.scrollToBottom()
      
      try {
        // 上传语音文件
        const formData = new FormData()
        formData.append('file', {
          uri: message.content,
          type: 'audio/mp3',
          name: 'voice.mp3'
        })
        const uploadRes = await uploadVoiceFile(formData)
        
        // 发送语音消息
        await sendVoiceMessage({
          url: uploadRes.url,
          duration: message.duration,
          type: 'voice'
        })
      } catch(e) {
        // 发送失败时从列表中移除
        const index = this.messageList.findIndex(item => item.id === message.id)
        if(index > -1) {
          this.messageList.splice(index, 1)
        }
        this.$modal.showToast('发送失败')
      }
    },

    // 播放语音
    playVoice(message) {
      // 停止当前正在播放的语音
      this.messageList.forEach(item => {
        if(item.type === 'voice') {
          item.isPlaying = false
        }
      })
      
      this.innerAudioContext.src = message.content
      this.innerAudioContext.play()
      message.isPlaying = true
      
      this.innerAudioContext.onEnded(() => {
        message.isPlaying = false
      })
    },

    // 加载历史消息
    async loadHistoryMessages() {
      if(this.loading) return
      
      this.loading = true
      try {
        const res = await getHistoryMessages({
          pageNum: this.pageNum,
          pageSize: this.pageSize,
          chatId: this.chatId,
          toUserId: this.toUserId
        })
        
        const { rows, total } = res.data
        this.total = total
        
        // 添加到消息列表
        rows.forEach(item => {
          item.showTime = true // 显示��间
          item.isPlaying = false // 语音播放状态
          // 判断是否是自己发送的消息
          item.isSelf = item.fromUserId === this.userInfo.userId
        })
        
        this.messageList = [...rows, ...this.messageList]
      } catch(e) {
        this.$modal.showToast('获取历史消息失败')
      } finally {
        this.loading = false
      }
    },

    // 加载更多历史消息
    async loadHistory() {
      if(this.loading) return
      if(this.messageList.length >= this.total) return
      
      this.pageNum++
      await this.loadHistoryMessages()
    },

    // 滚动到底部
    scrollToBottom() {
      setTimeout(() => {
        const query = uni.createSelectorQuery().in(this)
        query.select('.chat-list-content').boundingClientRect(data => {
          this.scrollTop = data.height * 2
        }).exec()
      }, 100)
    },

    // 处理发送按钮点击
    handleSend() {
      if(this.inputContent.trim()) {
        this.sendMessage()
      }
    }
  }
}
</script>

<style lang="scss">
.chat-container {
  display: flex;
  flex-direction: column;
  height: 100vh;
  background-color: #f5f5f5;
  
  // 聊天列表区域
  .chat-list {
    flex: 1;
    padding: 10px;
    
    .chat-time {
      text-align: center;
      font-size: 12px;
      color: #999;
      margin: 10px 0;
    }
    
    .chat-item {
      display: flex;
      margin-bottom: 20px;
      
      .avatar {
        width: 40px;
        height: 40px;
        border-radius: 4px;
      }
      
      .chat-content {
        max-width: 60%;
        margin: 0 15px;
      }
      
      .chat-text {
        padding: 10px 15px;
        border-radius: 4px;
        font-size: 16px;
        word-break: break-all;
      }
      
      .chat-voice {
        display: flex;
        align-items: center;
        padding: 10px 15px;
        border-radius: 4px;
        min-width: 80px;
        
        .voice-icon {
          width: 20px;
          height: 20px;
          
          .icon-voice {
            width: 100%;
            height: 100%;
            
            &.playing {
              animation: voicePlay 1s infinite;
            }
          }
        }
        
        .voice-duration {
          margin-left: 10px;
          color: #999;
          font-size: 14px;
        }
      }
    }
    
    .chat-item-left {
      .chat-content {
        .chat-text, .chat-voice {
          background-color: #fff;
        }
      }
    }
    
    .chat-item-right {
      flex-direction: row-reverse;
      
      .chat-content {
        .chat-text, .chat-voice {
          background-color: #95ec69;
        }
      }
    }
  }
  
  // 底部输入区域
  .chat-footer {
    display: flex;
    align-items: center;
    padding: 10px;
    background-color: #f9f9f9;
    border-top: 1px solid #eee;
    
    .mode-btn {
      padding: 0 10px;
      color: #666;
      
      .mode-icon {
        width: 24px;
        height: 24px;
      }
    }
    
    // 输入框和发送按钮的容器
    .input-wrapper {
      flex: 1;
      display: flex;
      align-items: center;
      background-color: #fff;
      border-radius: 4px;
      padding-right: 4px;
      
      .chat-input {
        flex: 1;
        height: 36px;
        padding: 0 10px;
        font-size: 16px;
        background-color: transparent;
      }
      
      .send-btn {
        padding: 4px 12px;
        border-radius: 4px;
        font-size: 14px;
        background-color: #e6e6e6;
        color: #999;
        
        &.send-btn-active {
          background-color: #07c160;
          color: #fff;
        }
      }
    }
    
    .voice-input {
      flex: 1;
      height: 36px;
      line-height: 36px;
      text-align: center;
      background-color: #fff;
      border-radius: 4px;
      color: #666;
    }
  }
  
  // 录音提示蒙层
  .record-modal {
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    background-color: rgba(0,0,0,0.3);
    display: flex;
    justify-content: center;
    align-items: center;
    
    .modal-content {
      width: 160px;
      height: 160px;
      background-color: rgba(0,0,0,0.6);
      border-radius: 10px;
      display: flex;
      flex-direction: column;
      justify-content: center;
      align-items: center;
      
      .record-tip {
        color: #fff;
        font-size: 14px;
        margin-bottom: 15px;
      }
      
      .volume-icon {
        width: 50px;
        height: 50px;
      }
    }
  }
}

@keyframes voicePlay {
  0% {
    opacity: 1;
  }
  50% {
    opacity: 0.5;
  }
  100% {
    opacity: 1;
  }
}
</style>
